import speech_recognition as sr
import os
from pydub import AudioSegment
from pydub.silence import split_on_silence
import sys

def transcribe_audio_file(file_path):
    """
    将音频文件转录为文本
    
    参数:
        file_path (str): 音频文件的路径
    
    返回:
        str: 转录的文本
    """
    # 检查文件是否存在
    if not os.path.exists(file_path):
        print(f"错误: 文件 '{file_path}' 不存在")
        return None
    
    # 检查文件是否为支持的音频格式
    if not (file_path.lower().endswith('.mp3') or file_path.lower().endswith('.wav')):
        print(f"错误: 文件 '{file_path}' 不是支持的音频格式（MP3或WAV）")
        return None
    
    # 获取文件名
    file_name = os.path.basename(file_path)
    print(f"正在处理音频文件: {file_name}")
    
    # 如果是MP3文件，先转换为WAV格式
    if file_path.lower().endswith('.mp3'):
        print("将MP3转换为WAV格式...")
        try:
            sound = AudioSegment.from_mp3(file_path)
            wav_path = file_path.replace('.mp3', '.wav').replace('.MP3', '.wav')
            sound.export(wav_path, format="wav")
            file_path = wav_path
            print(f"转换完成: {wav_path}")
        except Exception as e:
            print(f"转换MP3到WAV时出错: {e}")
            return None
    
    # 创建识别器
    recognizer = sr.Recognizer()
    
    # 对于较短的音频文件，直接进行转录
    try:
        # 加载音频文件
        audio_file = AudioSegment.from_file(file_path)
        
        # 如果音频文件小于30秒，直接转录
        if len(audio_file) < 30000:  # 30秒 = 30000毫秒
            with sr.AudioFile(file_path) as source:
                audio_data = recognizer.record(source)
                text = recognizer.recognize_google(audio_data, language="zh-CN")
                return text
        else:
            # 对于较长的音频，按静音分割并转录
            return transcribe_large_audio(file_path, recognizer)
    except Exception as e:
        print(f"转录过程中出错: {e}")
        return None

def transcribe_large_audio(path, recognizer):
    """
    将较长的音频文件分割成小块并转录
    
    参数:
        path (str): 音频文件的路径
        recognizer: 语音识别器实例
    
    返回:
        str: 转录的文本
    """
    # 打开音频文件
    sound = AudioSegment.from_file(path)
    
    # 按静音分割音频
    print("将音频分割成小块...")
    chunks = split_on_silence(
        sound,
        # 实验性参数，可根据目标音频文件调整
        min_silence_len=500,  # 最小静音长度（毫秒）
        silence_thresh=sound.dBFS-14,  # 静音阈值
        keep_silence=500,  # 保留静音时长（毫秒）
    )
    
    # 如果没有检测到足够的静音，使用固定间隔分割
    if len(chunks) <= 1:
        print("未检测到足够的静音，使用固定间隔分割...")
        chunk_length_ms = 10000  # 10秒
        chunks = [sound[i:i+chunk_length_ms] for i in range(0, len(sound), chunk_length_ms)]
    
    # 创建目录存储音频块
    folder_name = "audio-chunks"
    if not os.path.isdir(folder_name):
        os.mkdir(folder_name)
    
    whole_text = ""
    # 处理每个音频块
    for i, audio_chunk in enumerate(chunks, start=1):
        # 导出音频块并保存
        chunk_filename = os.path.join(folder_name, f"chunk{i}.wav")
        audio_chunk.export(chunk_filename, format="wav")
        print(f"处理音频块 {i}/{len(chunks)}")
        
        # 识别音频块
        try:
            with sr.AudioFile(chunk_filename) as source:
                audio_listened = recognizer.record(source)
                # 尝试转换为文本
                try:
                    text = recognizer.recognize_google(audio_listened, language="zh-CN")
                    text = f"{text}\n"
                    print(f"块 {i}: {text}")
                    whole_text += text
                except sr.UnknownValueError:
                    print(f"块 {i}: 无法识别语音")
                except Exception as e:
                    print(f"块 {i} 处理错误: {e}")
        except Exception as e:
            print(f"处理音频块 {i} 时出错: {e}")
    
    return whole_text

def main():
    # 检查命令行参数
    if len(sys.argv) < 2:
        print("使用方法: python audio_transcriber.py <音频文件路径>")
        return
    
    # 获取音频文件路径
    audio_file = sys.argv[1]
    
    # 转录音频文件
    transcribed_text = transcribe_audio_file(audio_file)
    
    if transcribed_text:
        print("\n转录结果:")
        print(transcribed_text)
        
        # 保存转录结果到文本文件
        output_file = os.path.splitext(audio_file)[0] + "_transcription.txt"
        with open(output_file, "w", encoding="utf-8") as f:
            f.write(transcribed_text)
        print(f"\n转录结果已保存到: {output_file}")

if __name__ == "__main__":
    main()